﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.IO;
using System.Collections.ObjectModel;
using Newtonsoft.Json;
using System.Net.Http.Headers;
using System.Net.Http;
using Microsoft.Win32;

namespace CrazyBubbleToolkit
{
    /// <summary>
    /// 主界面
    /// </summary>
    public partial class MainWindow : Window
    {
        private ObservableCollection<Stage> Stages = new ObservableCollection<Stage>();
        private StagesJson ServerStages = null; //存储所有关卡数据
        public static string levelData = "";    //所有关卡数据
        public static int levelIndex = -1;      //打开关卡位置
        public static MainWindow Instance;      

        public MainWindow()
        {
            InitializeComponent();
            listView1.ItemsSource = Stages;     //为listView添加数据源
            Instance = this;
        }

        /// <summary>
        /// 打开具体的关卡
        /// </summary>
        private void listView1_MouseDoubleClick(object sender, MouseButtonEventArgs e)
        {
            if (ServerStages == null)
            {
                MessageBox.Show("请先获取关卡数据");
                return;
            }
            var stg = listView1.SelectedItem as Stage;      //选中项的关卡信息
            var ss = ServerStages.Stages[int.Parse(stg.Index) - 1][int.Parse(stg.SubIndex) - 1];    //获取对应的关卡数据
            
            levelIndex = listView1.SelectedIndex+1;         //记录打开的关卡文件位置

            BubbleWindow bw = new BubbleWindow();
            bw.ShowAsDialog(stg, ss);

            //刷新列表界面
            for (int i = 0; i < Stages.Count; i++)
            {
                var s = Stages[i];
                var sss = ServerStages.Stages[int.Parse(s.Index) - 1][int.Parse(s.SubIndex) - 1];   //获取对应的关卡数据

                if (sss.BubbleGrids.Count > 0)
                {
                    s.Status = "已添加";

                    s.CanClear = true;
                    s.CanCopy = true;
                }
                else
                {
                    s.Status = "";

                    s.CanClear = false;
                    s.CanCopy = false;

                    if (PasteStatus.Tag == s)
                    {
                        PasteStatus.Tag = null;
                        PasteStatus.Text = "无数据";

                        foreach (var stg1 in Stages)
                        {
                            stg1.CanPaste = false;
                        }
                    }
                }

                if (sss.GridsType == 0)
                    s.Type = "收集能量";
                else if (sss.GridsType == 1)
                    s.Type = "拯救动物";
                else if (sss.GridsType == 2)
                    s.Type = "击退贱四狼";
                else if (sss.GridsType == 3)
                    s.Type = "收集能量时间压迫";
                else if (sss.GridsType == 4)
                    s.Type = "拯救动物时间压迫";
                else
                    s.Type = "未知关卡类型";
            }
        }

        private void button2_Click(object sender, RoutedEventArgs e)
        {
            Close();
        }

        //联网获取数据
        private void button1_Click(object sender, RoutedEventArgs e)
        {
            (sender as Button).IsEnabled = false;
            WaitingFrame.Visibility = Visibility.Visible;
            WaitingText.Visibility = Visibility.Visible;

            //get stages
            var http = new HttpClient();
            var req = new HttpRequestMessage(HttpMethod.Get, "http://czpanda.com:3099/query");
            try
            {
                http.SendAsync(req).ContinueWith(t =>
                {
                    var resp = t.Result;
                    if (resp.StatusCode != System.Net.HttpStatusCode.OK)
                    {
                        Application.Current.Dispatcher.Invoke(new Action(() =>
                            {
                                MessageBox.Show("network error");
                                (sender as Button).IsEnabled = true;
                                WaitingFrame.Visibility = Visibility.Collapsed;
                                WaitingText.Visibility = Visibility.Collapsed;
                            }));
                        return;
                    }
                    resp.Content.ReadAsStringAsync().ContinueWith( tt =>
                        {
                            var body = tt.Result;

                            //SaveToNativeFile(body.ToString(), "result", false);       //保存数据到本地
                            levelData = body.ToString();                               //保存数据

                            ServerStages = JsonConvert.DeserializeObject<StagesJson>(body);

                            Application.Current.Dispatcher.Invoke(new Action(() =>
                            {
                                (sender as Button).Content = "关卡数据已获取";
                                WaitingFrame.Visibility = Visibility.Collapsed;
                                WaitingText.Visibility = Visibility.Collapsed;

                                //
                                for (int s = 0; s < ServerStages.Stages.Count; s++)
                                {
                                    for (int sub = 0; sub < ServerStages.Stages[s].Count; sub++)
                                    {
                                        var stage = new Stage();
                                        stage.Index = (s + 1).ToString();
                                        stage.SubIndex = (sub + 1).ToString();
                                        stage.Status = "";

                                        Stages.Add(stage);
                                    }
                                }

                                for (int i = 0; i < Stages.Count; i++)
                                {
                                    var s = Stages[i];
                                    var ss = ServerStages.Stages[int.Parse(s.Index) - 1][int.Parse(s.SubIndex) - 1];

                                    if (ss.BubbleGrids.Count > 0)
                                    {
                                        s.Status = "已添加";
                                        s.CanClear = true;
                                        s.CanCopy = true;
                                    }

                                    if (ss.GridsType == 0)
                                        s.Type = "收集能量";
                                    else if (ss.GridsType == 1)
                                        s.Type = "拯救动物";
                                    else if (ss.GridsType == 2)
                                        s.Type = "击退贱四狼";
                                    else if (ss.GridsType == 3)
                                        s.Type = "收集能量时间压迫";
                                    else if (ss.GridsType == 4)
                                        s.Type = "拯救动物时间压迫";
                                    else
                                        s.Type = "未知关卡类型";
                                }


                            }));

                        });
                });

            }
            catch (Exception)
            {
            }
        }

        private void missionConvButton_Click(object sender, RoutedEventArgs e)
        {
            OpenFileDialog dlg = new OpenFileDialog();
            dlg.Filter = "json (.json)|*.json";
            dlg.Multiselect = true;
            dlg.InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.Desktop);

            Nullable<bool> result = dlg.ShowDialog();

            if (result == true)
            {
                string[] filenames = dlg.FileNames;
                foreach (var filepath in filenames)
                {
                    string newJson = null;
                    using (var fs = new StreamReader(filepath))
                    {
                        var content = fs.ReadToEnd();
                        content = content.Replace("mapassets.plist", "../mapassets.plist");
                        var obj = JsonConvert.DeserializeObject(content);
                        newJson = JsonConvert.SerializeObject(obj);
                    }

                    if (newJson != null)
                    {
                        using (var fs = new StreamWriter(filepath, false))
                        {
                            fs.Write(newJson);
                        }
                    }
                }

                MessageBox.Show("处理完成");
            }
        }

        private void ClearButton_Click(object sender, RoutedEventArgs e)
        {
            var btn = sender as Button;
            var stage = btn.Tag as Stage;

            //让对应行高亮
            listView1.SelectedItem = stage;
            var msg = "确认清空 " + stage.Index + " - " + stage.SubIndex + " 的关卡数据？";
            if (MessageBox.Show(msg, "警告", MessageBoxButton.OKCancel) == MessageBoxResult.OK)
            {
                WaitingFrame.Visibility = Visibility.Visible;
                WaitingText.Visibility = Visibility.Visible;

                var http = new HttpClient();
                var req = new HttpRequestMessage(HttpMethod.Post, "http://czpanda.com:3099/save");

                var queryBuilder = new QueryStringBuilder();
                queryBuilder.Add("v", "1");
                queryBuilder.Add("s1", (int.Parse(stage.Index) - 1).ToString());
                queryBuilder.Add("s2", (int.Parse(stage.SubIndex) - 1).ToString());
                queryBuilder.Add("d", "{}");

                var query = queryBuilder.ToQueryString(false);

                req.Content = new StringContent(query, Encoding.UTF8);
                req.Content.Headers.ContentType = new MediaTypeHeaderValue("application/x-www-form-urlencoded");
                try
                {
                    http.SendAsync(req).ContinueWith(t =>
                    {
                        var resp = t.Result;
                        resp.Content.ReadAsStringAsync().ContinueWith(tt =>
                        {
                            var body = tt.Result;

                            Application.Current.Dispatcher.Invoke(new Action(() =>
                            {
                                if (body == "Ok")
                                {
                                    MessageBox.Show("提交成功");

                                    //清空实际的关卡数据
                                    var newStageData = JsonConvert.DeserializeObject<StageData>("{}");
                                    ServerStages.Stages[int.Parse(stage.Index) - 1][int.Parse(stage.SubIndex) - 1] = newStageData;

                                    stage.Status = "";
                                    stage.CanClear = false;
                                    stage.CanCopy = false;

                                    //如果当前小关在剪贴板上，则清空剪贴板
                                    if (PasteStatus.Tag == stage)
                                    {
                                        PasteStatus.Text = "无数据";
                                        PasteStatus.Tag = null;

                                        //禁用所有的粘贴按钮
                                        foreach (var s in Stages)
                                        {
                                            s.CanPaste = false;
                                        }
                                    }
                                }
                                else
                                {
                                    MessageBox.Show("提交失败");
                                }

                                WaitingFrame.Visibility = Visibility.Collapsed;
                                WaitingText.Visibility = Visibility.Collapsed;

                            }));

                        });
                    });

                }
                catch (Exception)
                {
                }
            }
        }

        private void CopyButton_Click(object sender, RoutedEventArgs e)
        {
            var btn = sender as Button;
            var stage = btn.Tag as Stage;

            //让对应行高亮
            listView1.SelectedItem = stage;

            PasteStatus.Text = stage.Index + " - " + stage.SubIndex;
            PasteStatus.Tag = stage;

            foreach (var s in Stages)
            {
                s.CanPaste = s == stage ? false : true;
            }
        }

        private void PasteButton_Click(object sender, RoutedEventArgs e)
        {
            var btn = sender as Button;
            var stage = btn.Tag as Stage;

            //让对应行高亮
            listView1.SelectedItem = stage;

            var sourceStage = PasteStatus.Tag as Stage;
            var stageData = ServerStages.Stages[int.Parse(stage.Index) - 1][int.Parse(stage.SubIndex) - 1];
            var msg = "确认用" + sourceStage.Index + " - " + sourceStage.SubIndex + " 的关卡数据覆盖 "
                + stage.Index + " - " + stage.SubIndex + " ？";
            if (stageData.BubbleGrids.Count > 0 && MessageBox.Show(msg, "警告", MessageBoxButton.OKCancel) != MessageBoxResult.OK)
                return;

            WaitingFrame.Visibility = Visibility.Visible;
            WaitingText.Visibility = Visibility.Visible;

            var http = new HttpClient();
            var req = new HttpRequestMessage(HttpMethod.Post, "http://czpanda.com:3099/save");

            var queryBuilder = new QueryStringBuilder();
            queryBuilder.Add("v", "1");
            queryBuilder.Add("s1", (int.Parse(stage.Index) - 1).ToString());
            queryBuilder.Add("s2", (int.Parse(stage.SubIndex) - 1).ToString());

            var sourceStageData = ServerStages.Stages[int.Parse(sourceStage.Index) - 1][int.Parse(sourceStage.SubIndex) - 1];
            sourceStageData.Compress();
            var sdJson = JsonConvert.SerializeObject(sourceStageData);
            //将{"t":0}替换成{}，进一步压缩json体积
            var emptyStageBubbleJson = JsonConvert.SerializeObject(new Bubble());
            sdJson = sdJson.Replace(emptyStageBubbleJson, "{}");
            queryBuilder.Add("d", sdJson);

            var query = queryBuilder.ToQueryString(false);

            req.Content = new StringContent(query, Encoding.UTF8);
            req.Content.Headers.ContentType = new MediaTypeHeaderValue("application/x-www-form-urlencoded");
            try
            {
                http.SendAsync(req).ContinueWith(t =>
                {
                    var resp = t.Result;
                    resp.Content.ReadAsStringAsync().ContinueWith(tt =>
                    {
                        var body = tt.Result;

                        Application.Current.Dispatcher.Invoke(new Action(() =>
                        {
                            if (body == "Ok")
                            {
                                MessageBox.Show("提交成功");
                                stage.Status = "已添加";
                                stage.CanClear = true;
                                stage.CanCopy = true;

                                //更新实际的关卡数据
                                var newStageData = JsonConvert.DeserializeObject<StageData>(sdJson);
                                ServerStages.Stages[int.Parse(stage.Index) - 1][int.Parse(stage.SubIndex) - 1] = newStageData;
                            }
                            else
                            {
                                MessageBox.Show("提交失败");
                            }

                            WaitingFrame.Visibility = Visibility.Collapsed;
                            WaitingText.Visibility = Visibility.Collapsed;

                        }));

                    });
                });

            }
            catch (Exception)
            {
            }
        }


        #region 本地关卡数据相关操作

        //打开本地关卡数据
        private void button3_Click(object sender, RoutedEventArgs e)
        {
            //打开文件
            OpenFileDialog dialog = new OpenFileDialog();
            dialog.InitialDirectory = System.AppDomain.CurrentDomain.BaseDirectory; //使用当前目录作为初始目录
            dialog.Filter = "json文件(*.json)|*.json";          //仅打开json
            dialog.Multiselect = true;                          //多个文件

            //
            if (dialog.ShowDialog().Value)
            {
                //string data = ToString(dialog.FileName);        //读取文件数据

                //data = levelsData(data);
                string data = getFilesLevelData(dialog.FileNames);//"#"分隔的关卡数据
                data = ToStagesJson(data);                        //转化为StagesJson串

                dataInput(data);
            }
        }

        //从多个文件中读取所有关卡数据,以"#"分隔
        private string getFilesLevelData(string[] Files)
        {
            string levels = "";
            string data = "";
            for (int i = 0; i < Files.Length; i++)
            {
                data = ToString(Files[i]);        //读取文件数据
                levels += levelsData(data);       //获取关卡数据串,以"#"分隔

                if (i < Files.Length - 1) levels += "#";
            }

            return levels;
        }

        //获取关卡文件串中的关卡数据,以"#"分隔
        private string levelsData(string data)
        {
            //data = data.Replace("{\"v\":1,\"dat\":[[", "");

            string data2 = "";

            data = data.Replace("]]}", "");                             //去除串尾"]]}"
            data = data.Replace("{\"gt\":", "#{\"gt\":");               //添加特殊分割符#
            string[] datas = data.Split('#');                           //对关卡数据进行分割处理，datas[0]不是关卡数据

            for (int i = 1; i < datas.Length; i++)
            {
                datas[i] = levelTrim(datas[i]);
                data2 += datas[i];
                if (i < datas.Length - 1) data2 += "#";
            }
            return data2;
        }

        //将以"#"分割的关卡数据转化为StagesJson数据
        private string ToStagesJson(string levelsData)
        {
            string json = "{\"v\":1,\"dat\":[";

            string[] levels = levelsData.Split('#');        //所有关卡数据
            string tmp = "";
            for (int i = 1; i <= levels.Length; i++)
            {
                if (i % 20 == 1) tmp = "[";
                tmp += levels[i - 1];

                if (i % 20 == 0 || i == levels.Length)      //每20关做为一个大关
                {
                    tmp += "]";
                    json += tmp;
                    if (i < levels.Length) json += ",";

                    tmp = "";
                }
                else tmp += ",";
            }

            json += "]}";
            return json;
        }

        //获取关卡数据
        private string levelTrim(string levelData)
        {
            string tmp = levelData.Substring(levelData.Length - 3, 3);
            if (tmp.Equals("],[")) levelData = levelData.Substring(0, levelData.Length - 3);//去除串尾部"],["
            tmp = levelData.Substring(levelData.Length - 1, 1);
            if (tmp.Equals(",")) levelData = levelData.Substring(0, levelData.Length - 1);//去除串尾部","
            tmp = levelData.Substring(levelData.Length - 1, 1);
            if (tmp.Equals("]")) levelData = levelData.Substring(0, levelData.Length - 1);//去除串尾部"]"

            return levelData;
        }

        /// <summary>
        /// 获取文件中的数据串
        /// </summary>
        public string ToString(String filePath)
        {
            string str = "";

            //获取文件内容
            if (System.IO.File.Exists(filePath))
            {
                System.IO.StreamReader file1 = new System.IO.StreamReader(filePath);//读取文件中的数据
                str = file1.ReadToEnd();                                            //读取文件中的全部数据

                file1.Close();
                file1.Dispose();
            }
            return str;
        }

        //输入关卡数据前，先对关卡数据进行分割，20个小关分为一个大关
        public void dataInput2(string data)
        {
            data = levelsData(data);        //"#"分隔的关卡数据
            data = ToStagesJson(data);      //转化为StagesJson串

            dataInput(data);
        }

        //显示本地文件中的数据
        public void dataInput(string data)
        {
            levelData = data;                               //保存数据

            var body = data;
            ServerStages = JsonConvert.DeserializeObject<StagesJson>(body);

            Application.Current.Dispatcher.Invoke(new Action(() =>
            {
                //(sender as Button).Content = "关卡数据已获取";
                //WaitingFrame.Visibility = Visibility.Collapsed;
                //WaitingText.Visibility = Visibility.Collapsed;

                //关卡总体信息在ListView中的显示
                Stages.Clear();
                for (int s = 0; s < ServerStages.Stages.Count; s++)
                {
                    for (int sub = 0; sub < ServerStages.Stages[s].Count; sub++)
                    {
                        var stage = new Stage();
                        stage.Index = (s + 1).ToString();       //大关
                        stage.SubIndex = (sub + 1).ToString();  //小关卡编号
                        stage.Status = "";

                        Stages.Add(stage);
                    }
                }

                for (int i = 0; i < Stages.Count; i++)
                {
                    var s = Stages[i];
                    var ss = ServerStages.Stages[int.Parse(s.Index) - 1][int.Parse(s.SubIndex) - 1];

                    if (ss.BubbleGrids.Count > 0)
                    {
                        s.Status = "已添加";
                        s.CanClear = true;
                        s.CanCopy = true;
                    }

                    if (ss.GridsType == 0)
                        s.Type = "收集能量";
                    else if (ss.GridsType == 1)
                        s.Type = "拯救动物";
                    else if (ss.GridsType == 2)
                        s.Type = "击退贱四狼";
                    else if (ss.GridsType == 3)
                        s.Type = "收集能量时间压迫";
                    else if (ss.GridsType == 4)
                        s.Type = "拯救动物时间压迫";
                    else
                        s.Type = "未知关卡类型";
                }


            }));
        }

        //鼠标单击显示关卡编号
        private void listView1_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
        }

        private void listView1_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            this.Title = "大头儿子小头爸爸版编辑器 - " + (listView1.SelectedIndex + 1);
        }

        #endregion

    }


    class StagesJson
    {
        [JsonProperty("v")]
        public int Version { get; set; }

        [JsonProperty("dat")]
        public List<List<StageData>> Stages { get; set; }
    }

}
